#include <cassert>
#include "../core/i_blas.h"
#include "../core/i_alloc.h"
#include "../ip/i_integral.h"
#include "i_brief.h"

namespace idl
{
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  InterestPointBrief128::InterestPointBrief128()
  {
    this->type = 0;
    this->x = this->y = this->scale = this->orientation = this->response = 0.f;
    i_zero4(this->descriptor);
  }
  InterestPointBrief128::~InterestPointBrief128(){}

  InterestPointBrief256::InterestPointBrief256()
  {
    this->type = 0;
    this->x = this->y = this->scale = this->orientation = this->response = 0.f;
    i_zero8(this->descriptor);
  }
  InterestPointBrief256::~InterestPointBrief256(){}

  InterestPointBrief512::InterestPointBrief512()
  {
    this->type = 0;
    this->x = this->y = this->scale = this->orientation = this->response = 0.f;
    i_zero16(this->descriptor);
  }
  InterestPointBrief512::~InterestPointBrief512(){}
  
  /*BRIEF Feature descriptor implementation*/
  InterestPointDescriptorBrief::InterestPointDescriptorBrief(const int width, const int height, float ipt_scale_base) : _width(width), _height(height), _base_scale(ipt_scale_base)
  {
    /*the base scale of Fast-Hessian feature.*/
    int size_offset;

    /*nbhd size 33x33:*/
    const int offset_33x33[] =
    {
      10, 6, 7, -11, -7, -1, 10, 2, -8, -4, 4, 1, -1, 7, -13, -1, 2, 4, -4, -4, -9, 8, -3, -5, -5, -5, 0, 5, -3, -1, 11, -9, -10, 6, -12, -5, -1, -10, 9, 0, -5, 11, -5, 3, -12, 2, 4, 4, -1, 7, -15, -9, 7, 0, 1, 5, -7, 10, -3, 1, 5, -3, 2, 14, -3, -12, 11, 3, -4, -2, 4, -1, -6, -9, 2, -4, -9, 3, 9, 11, 15, 4, 8, -2, 0, 5, 2, -7, 0, -2, 16, -10, -3, 4, -7, -7, 10, -2, -4, -5, -8, -10, 6, 12, -5, -11, -1, 2, -6, 0, 0, -3, -1, 6, 0, -3, 11, 0, -4, -2, 10, 2, 3, 1, 2, -2, -3, 4, 7, -3, 6, -14, 4, -11, -11, -2, -7, 9, 0, 10, -5, -3, 4, 2, 3, -5, -7, 7, -3, -9, -1, 0, -8, 1, 8, -1, -4, -6, 12, -10, -6, -3, 4, 9, -3, -7, 0, 1, -3, 8, 5, 0, 1, 12, 4, -4, -6, -12, 0, 14, 0, 9, 1, -5, -5, -7, 12, -1, -16, 1, 1, 1, -6, 4, -6, -13, -4, 8, 4, -1, -8, 7, 4, 14, -3, 1, 4, 0, -3, 5, 11, 0, -1, 4, 16, -3, 0, 9, -3, -5, -5, -5, 6, -5, 6, 6, 2, 0, -5, 3, 2, 3, -1, 5, -7, -9, -8, 4, -4, -15, -1, -10, -2, 8, 10, 1, -3, -8, 3, -4, -4, -4, -4, 7, 10, 5, 4, 1, -7, -2, 8, 9, 1, 6, 7, 11, 15, 2, -2, -2, -9, -4, -5, 12, -2, -8, -1, 11, -15, -11, 3, 1, -8, -2, 0, 11, 6, -6, -3, 0, -7, -9, -2, -13, -2, 1, 8, -10, -4, 0, -7, 6, -1, 3, 0, 1, 9, 2, -6, -5, 2, 5, 3, -4, -7, 9, 0, 9, -14, 7, 14, 7, -7, 1, 2, -5, -6, 3, -1, 4, 6, -6, -4, 10, 4, -2, 3, -2, -10, -1, -3, -14, -3, 0, 3, -4, -7, 8, -4, -4, 7, -2, 5, -6, 5, 3, 3, 11, 4, 3, -2, -2, 6, 9, -7, -5, -3, 4, 12, -3, 0, -9, -2, -4, 13, 6, 1, -2, -1, 6, -1, 1, 13, -9, 1, -1, -4, -6, 5, 7, 3, 0, 9, -1, -1, -11, -7, 15, -7, -9, 2, 13, -4, -6, -13, 8, 1, 7, 12, 0, -4, 5, -7, 3, 7, -1, 4, 1, 8, 7, -1, 3, 3, -9, 0, 5, 8, -6, 2, 1, 7, -9, 10, 5, 10, -6, -2, -3, 8, 15, 2, -6, 3, -13, 2, 7, 14, -10, 1, 5, -6, 2, 1, -8, 6, -2, -4, -9, 7, 1, 1, -1, -6, 9, -2, 5, 5, 5, 4, 7, -4, 5, -4, -8, 8, -3, 5, -1, 9, -9, 3, 4, 10, 5, 0, 4, -8, 9, 15, 5, -5, -9, -9, -4, -6, 5, 2, -11, -10, 15, -10, -6, 0, 9, 3, 3, -5, 2, -2, -7, -6, -13, 3, 6, -8, 6, -1, -8, 3, -1, -3, 2, 1, -6, 0, -3, 6, 10, -8, 6, 2, -4, 12, -8, -3, 4, -2, 4, 4, -15, -8, 2, 4, 14, 5, -4, -1, 3, -1, -5, -7, 10, -1, -1, -2, -10, -2, 5, 6, -1, 3, -7, 5, 1, 0, -2, 0, 6, 3, 2, -7, 14, 9, -5, -5, 0, -3, -9, 5, 4, -10, -3, 0, -9, -4, 1, -13, -8, -6, 2, -7, 13, 2, 0, -7, 2, -7, -2, 1, 1, 4, -5, -3, 9, 9, -7, -14, -12, -6, 1, 7, -4, -8, 1, -1, -5, 14, -6, -2, 0, -10, 5, 1, 5, -9, 11, 12, -1, 1, -4, -5, 10, 1, -6, -9, -4, -16, -11, 0, -11, -6, -1, -1, -13, 14, 2, -8, 0, -6, 0, 12, -11, -16, -8, -4, 1, 7, 2, -6, 1, 1, 16, -6, 7, -3, 8, 5, 7, 3, 2, 10, 2, 6, -12, -3, -1, -1, 6, -7, -3, 8, 9, 0, -11, 9, 2, 3, -4, -2, 3, 5, -2, -7, -7, 12, 1, 0, -14, -7, 1, -2, -3, -7, 12, -1, 7, 7, 1, -2, -5, -1, 13, -3, 15, 3, 6, -2, -9, 5, -5, -4, 2, 1, 14, -5, 5, 9, 3, -8, 14, 3, 3, 12, -12, -2, 4, -2, -7, -1, 1, -3, -10, -8, 0, -5, -9, 2, 4, -1, 3, 5, -4, -5, -3, -10, 3, -5, -5, 8, 2, 11, 0, 4, -10, -11, 4, -5, 10, 3, 6, 9, 1, -14, -1, 5, 10, 12, 9, 15, -3, 8, -3, -11, -10, 6, 3, 2, -7, 6, 5, -7, -1, -8, -10, -2, 5, 2, -4, -10, -2, -2, -8, 8, 4, 0, -15, 5, 7, -10, 8, 10, -4, 7, -4, 5, 13, -5, -3, 3, -1, -12, 15, -11, 0, -7, 3, 11, -5, -4, -2, -5, -11, 1, 8, -2, -1, -2, 1, -8, -5, -13, -12, -3, 4, 1, -2, 3, 9, -5, 3, 0, -5, 4, -11, 4, 9, 5, 7, 13, -3, 3, 1, 13, 3, -1, 1, 6, -1, 11, -4, -1, -4, 4, -1, -5, -9, 0, 3, 6, 7, 4, -2, -9, 5, -6, -5, 7, 4, 4, 1, -11, 1, -9, 6, -16, 8, 2, 2, -9, 12, 4, -2, -12, 1, 1, -10, 5, -4, -13, 2, 2, -6, 1, 9, 12, -1, 4, 1, -3, -8, 12, 7, 5, 3, 6, -10, 6, 2, -4, -7, -13, 8, -3, 2, 10, -6, -3, 2, -8, -4, -13, 5, 1, 6, 0, 6, -10, 9, -10, 2, 13, 2, -2, 14, 5, -7, 4, 16, 12, -7, 0, -6, 6, -1, 0, -5, -10, 8, -6, 2, 7, 3, -5, -2, 6, -1, 2, -9, -4, -6, -9, 7, 3, 3, 3, 1, -13, 9, 3, 0, -7, -8, 0, 7, -6, 3, 3, 5, -4, -9, -1, 9, -6, 1, 8, -14, -6, -5, -9, 1, 1, 3, -4, -15, 3, -7, -6, 0, 2, 10, 0, -10, -15, -3, 13, 2, -9, 4, 1, 1, -6, -10, -5, -4, 5, 7, 0, 6, -2, -9, -9, -3, 0, 0, 7, 6, 13, -3, -8, 0, 4, 3, 6, -2, -11, 7, -3, -4, 5, -2, 11, 8, -3, 2, 8, 1, -1, -7, 0, 5, -1, -8, 4, -10, 8, 8, 2, 3, 2, -7, -1, 7, -2, -6, -6, 4, -8, -4, -5, 4, 4, -1, 3, -2, -1, 4, -4, -4, 12, 0, -7, 4, 3, -5, -11, 8, -4, 9, 6, 11, 2, 3, 6, -3, 3, 3, 4, -12, 11, -2, -4, -4, 1, 5, -4, -5, 12, -3, -2, -7, -9, -3, -1, -5, -6, 2, -2, 6, 6, -14, -1, 3, -2, -8, -3, 2, 2, -4, 6, 0, -5, 5, 15, -4, -8, 5, 7, -6, -15, 5, 2, -6, 7, -16, -13, -6, -6, -4, -5, 5, 9, -1, -2, -1, 8, -4, -13, 5, 4, 7, 1, -2, 12, 1, -5, 9, 16, 4, 8, -5, -1, -1, -6, -10, -5, 1, -7, -3, 1, -2, 5, 10, 11, 3, 11, 4, -1, -3, -2, 15, 11, -7, 5, -4, -5, -8, 2, 6, -1, 15, 8, 2, 4, 12, -1, 9, 7, -1, 3, 8, 0, -2, -3, 3, 10, -14, 5, -3, -9, -4, -3, 1, 4, -3, -7, 7, -4, -5, 14, 2, -3, -8, -1, 2, 14, -4, 3, -1, 5, 10, -12, 1, -5, 0, -7, -15, 6, -5, 6, -1, -4, -6, 5, 12, 7, -5, 9, -2, 2, 0, 5, -6, -7, -3, 2, 1, 11, 0, 9, 3, -12, 7, -7, 9, 7, 5, -4, 9, -15, 1, 1, -1, -7, -2, 8, 1, 3, -6, 6, 15, 1, -4, 5, 3, -8, 5, -9, -3, -8, 5, -3, -12, -3, 10, 10, 8, 6, -6, 4, -2, -5, -11, 7, 9, 3, 0, -2, -3, 7, -5, -1, -6, -4, 13, 1, 3, 2, -4, -2, -5, -6, 14, -10, 2, 6, -3, -10, -10, -1, 4, -5, 1, 7, -8, 1, 4, -12, -8, -6, -2, 0, 1, 2, 3, -6, -3, 10, -5, -5, 1, 2, -3, -13, -2, 2, 11, -2, 1, -5, -2, 16, -10, -4, -11, 5, -10, -8, 5, 1, -2, 5, -10, 1, 13, -7, -3, -1, -9, -6, -4, 3, -3, -4, 2, 1, -14, -2, 11, -16, 5, 0, -4, -9, 9, 9, -6, -7, 12, 3, -2, -7, -2, -9, -4, 15, -6, -5, 5, 3, 5, 7, 0, 0, -2, 4, 5, -4, 2, -13, 8, 12, 3, -14, 9, 3, 2, 3, -11, 0, 8, 1, 1, 5, 12, -7, 13, -9, -13, -8, -4, 4, -10, 1, 12, 6, -12, -1, 4, 15, 9, 4, 2, -7, -14, 4, -6, -9, -6, -10, 9, 4, -4, 0, -5, 2, 7, -3, 8, 5, 4, 1, 0, -5, -3, 10, -4, 6, 4, 7, -2, -2, 10, 10, 8, 5, -6, 7, -11, -2, 3, 6, -10, 3, 0, -7, -6, -5, 6, -3, 6, -2, -3, -1, -4, 1, 11, 10, -5, -3, -11, -4, -11, -5, 1, -3, 10, 5, 2, 5, -1, -3, -9, -5, -5, -2, 15, -3, 8, -13, 2, 12, -1, 5, -6, 1, 14, 4, 3, 10, 2, -1, 3, -5, 8, -11, -4, 3, -2, -3, 1, 3, 16, -12, -5, 4, 9, -2, -13, 6, -1, -1, -2, -5, -8, -16, 15, 11, 3, -8, -13, -8, 3, 14, 8, -1, 4, 10, 7, -5, -1, -12, -4, -9, -9, 0, -4, 0, -3, 7, -7, -1, -11, -9, -16, 4, -3, 5, -11, 4, -3, -7, 3, 2, -7, -9, -10, 8, -5, 0, 1, -2, -4, 2, 8, 5, 13, -3, -6, 3, -11, 5, 4, -15, -6, -8, -4, 3, 14, -9, 5, -11, -8, -7, 12, 4, 1, -2, 10, -8, -9, 2, -7, 3, 2, -9, 1, -7, -10, -1, 1, -8, -4, 2, 6, 2, -3, -2, 9, 7, -11, 9, 6, -8, 1, 8, 7, -6, 0, 6, -2, -5, 7, 6, -4, 12, -8, -8, 2, -12, 10, 7, -3, 9, 0, -4, 0, 3, 2, -9, 13, -4, -4, 2, 6, -5, -3, 5, -1, 13, 1, 1, -8, -2, 3, -3, -5, -1, -6, 8, 9, -8, 3, 1, 7, 3, 0, -4, 15, -5, -4, 2, -11, -2, -1, -2, 9, 1, 4, -6, -6, 0, -10, -4, 1, 12, 7, -9, -4, -7, -16, -4, -10, 4, -4, -11, -14, -5, -9, -2, -2, -3, -4, -6, 4, 9, 12, -11, 3, 12, -5, 1, -5, -5, 4, 0, 10, 0, 10, 1, -2, -6, 3, 10, -1, 13, 0, 8, 6, 7, 6, 6, -5, 3, 8, -11, -1, 8, 10, 12, -7, 7, 7, -9, 5, -1, 16, -9, -4, 4, 3, 0, -11, -8, 6, -2, 3, 10, 1, -5, -10, 8, -8, 6, 6, 9, -14, -11, 2, 6, 10, 10, 2, 9, -4, 4, 5, 0, 0, 2, 7, 5, -12, -2, -6, -5, 1, 5, -1, -3, 8, 8, 12, -3, 7, 3, 1, -3, -2, -10, 1, -3, -15, 2, 1, -4, -4, -7, -10, 16, 0, 1, -12, 6, 10, 8, 2, 0, -6, 5, 4, -10, 6, 12, 0, 10, 1, -5, 3, -12, -1, -1, 9, -2, -2, -4, 5, -1, 8, 7, 2, -4, -10, -1, 0, 4, -1, -4, -2, 11, -5, 7, 8, 3, -3, -4, -8, 2, -9, -5, -3, -1, -11, -7, 2, 0, -10, -12, -2, 8, 4, 6, -8, -5, 13, -15, 2, 7, -6, 7, 9, -1, -2, 6, 3, -7, 1, 16, 0, 13, -4, 5, 13, 1, 5, 5, -6, -7, 4, 2, -9, -2, -9, 5, -5, 0, -13, -6, 2, -8, 2, 5, 5, -8, -13, -5, -4, 12, -4, 5, -1, -5, -7, 2, 7, -8, 6, 4, 6, 7, 5, -12, -9, 7, 0, -7, -12, 2, -6, -8, 3, 2, 10, -1, -11, 11, 3, -10, 15, 13, -1, 2, -3, 3, 2, -11, 4, -5, 11, 15, -2, 5, -1, -1, -10, -10, 5, 9, -9
    };

    /*nbhd size 49x49:*/
    const int offset_49x49[] =
    {
      15, 8, 10, -16, -10, -2, 15, 3, -12, -7, 6, 2, -1, 10, -19, -2, 3, 7, -7, -6, -13, 12, -4, -7, -8, -8, 0, 7, -4, -2, 16, -14, -15, 9, -18, -8, -1, -15, 14, 0, -8, 16, -7, 4, -18, 4, 6, 6, -2, 11, -23, -13, 10, 1, 2, 8, -10, 14, -5, 1, 8, -5, 3, 21, -5, -17, 17, 5, -5, -4, 7, -1, -9, -14, 3, -6, -14, 4, 13, 16, 22, 5, 13, -4, -1, 8, 3, -10, 0, -4, 23, -15, -4, 6, -11, -10, 15, -2, -6, -8, -12, -14, 8, 17, -7, -17, -2, 3, -9, 0, 0, -5, -2, 9, 0, -4, 16, 0, -6, -4, 16, 4, 4, 1, 2, -3, -4, 6, 10, -5, 9, -21, 6, -17, -16, -2, -10, 13, 0, 15, -7, -5, 6, 3, 4, -7, -10, 11, -5, -14, -1, 1, -12, 1, 11, -1, -6, -8, 18, -15, -9, -4, 5, 13, -4, -10, -1, 1, -4, 12, 7, -1, 2, 18, 5, -7, -9, -17, 0, 21, 0, 13, 2, -7, -8, -10, 17, -2, -23, 2, 1, 1, -9, 6, -9, -19, -7, 12, 6, -2, -12, 11, 6, 21, -5, 1, 6, 0, -4, 8, 16, 0, -2, 5, 24, -4, 0, 14, -5, -8, -7, -7, 9, -7, 9, 9, 3, 0, -8, 5, 4, 4, -1, 7, -11, -13, -12, 6, -5, -22, -2, -15, -3, 12, 15, 1, -5, -12, 4, -5, -7, -6, -6, 11, 15, 7, 7, 2, -10, -3, 11, 13, 2, 9, 10, 16, 22, 3, -2, -4, -13, -7, -8, 18, -3, -12, -2, 17, -22, -16, 4, 1, -12, -4, 0, 16, 9, -8, -5, -1, -10, -14, -3, -19, -3, 2, 12, -15, -6, -1, -11, 9, -1, 5, 1, 1, 14, 3, -9, -7, 4, 7, 4, -6, -10, 13, -1, 13, -21, 10, 21, 11, -10, 1, 3, -8, -9, 4, -2, 6, 9, -9, -7, 15, 7, -3, 5, -3, -15, -2, -5, -21, -4, 1, 4, -6, -10, 12, -6, -6, 10, -2, 7, -10, 7, 4, 5, 17, 7, 4, -3, -3, 8, 13, -10, -8, -5, 6, 17, -5, 0, -14, -3, -6, 20, 9, 1, -3, -2, 9, -2, 1, 20, -13, 1, -2, -6, -9, 7, 11, 5, -1, 14, -1, -2, -16, -10, 22, -10, -14, 2, 20, -6, -9, -19, 12, 1, 10, 18, 0, -5, 8, -11, 4, 11, -1, 7, 1, 12, 10, -1, 4, 5, -14, 0, 8, 11, -8, 3, 2, 10, -13, 15, 8, 14, -8, -3, -5, 12, 22, 3, -8, 5, -19, 3, 10, 20, -14, 2, 7, -10, 3, 2, -12, 9, -3, -5, -13, 10, 2, 2, -2, -8, 14, -3, 8, 7, 7, 13, -7, 3, -2, 6, 10, -5, 8, -6, -12, 12, -5, 7, -1, 13, -13, 5, 6, 15, 7, 1, 6, -12, 13, 22, 7, -8, -14, -13, -6, -8, 8, 3, -16, -15, 22, -15, -9, 0, 13, 4, 5, -7, 3, -3, -11, -9, -19, 5, 9, -12, 9, -1, -12, 5, -2, -5, 3, 2, -9, 0, -4, 9, 15, -12, 8, 3, -6, 17, -11, -5, 7, -3, 6, 6, -22, -11, 4, 6, 20, 7, -5, -2, 4, -2, -8, -11, 15, -2, -1, -3, -15, -3, 7, 9, -1, 4, -10, 8, 2, 0, -3, 0, 9, 4, 3, -10, 21, 14, -8, -7, -1, -5, -14, 7, 6, -15, -5, 0, -13, -6, 1, -19, -12, -9, 3, -10, 20, 3, 0, -11, 4, -10, -3, 1, 1, 6, -7, -4, 14, 13, -11, -20, -18, -9, 2, 11, -6, -11, 2, -1, -8, 21, -8, -4, 1, -15, 8, 1, 7, -14, 17, 18, -2, 1, -6, -8, 15, 2, -9, -14, -6, -24, -17, 0, -17, -9, -1, -1, -20, 21, 3, -12, 0, -9, 0, 18, -16, -23, -11, -7, 1, 0, -7, 7, -15, 10, 4, -9, 2, 2, 24, -9, 10, -4, 13, 7, 10, 5, 3, 15, 3, 9, -18, -4, -2, -2, 9, -10, -4, 13, 13, 1, -16, 13, 3, 5, -6, -2, 5, 8, -3, -11, -10, 18, 1, 1, -21, -10, 1, -3, -4, -11, 18, -2, 11, 11, 1, -3, -7, -2, 19, -5, 22, 4, 9, -2, -14, 8, -8, -5, 3, 2, 21, -7, 7, 14, 4, -12, 20, 5, 4, 18, -18, -4, 6, -3, -11, -1, 1, -5, -14, -11, 0, -7, -13, 3, 6, -1, 5, 8, -5, -7, -5, -15, 5, -8, -8, 12, 3, 17, 0, 5, -14, -17, 7, -7, 14, 4, 9, 13, 2, -20, -2, 8, 15, 18, 13, 23, -5, 12, -4, -16, -15, 9, 4, 2, -10, 9, 7, -10, -1, -11, -15, -3, 7, 3, -6, -15, -3, -3, -13, 12, 6, 0, -23, 8, 11, -15, 12, 14, -5, 10, -6, 7, 19, -7, -5, 4, -2, -17, 23, -16, -1, -10, 4, 17, -7, -6, -3, -7, -16, 2, 11, -3, -1, -3, 1, -12, -7, -20, -18, -4, 6, 2, -2, 4, 14, -7, 5, 0, -7, 5, -16, 6, 13, 8, 10, 20, -4, 4, 1, 20, 4, -1, 2, 9, -2, 16, -7, -2, -6, 5, -1, -7, -14, 0, 5, 9, 10, 6, -3, -13, 7, -9, -8, 11, 6, 6, 1, -16, 2, -14, 9, -24, 11, 3, 3, -14, 18, 7, -3, -18, 1, -20, 3, 3, -9, 2, 14, 17, -1, 5, 2, -4, -12, 18, 10, 8, 4, 9, -15, 9, 3, -6, -10, -20, 12, -5, 3, 15, -10, -5, 3, -11, -6, -19, 7, 1, 10, 0, 9, -15, 14, -14, 3, 19, 4, -3, 21, 7, -10, 6, 23, 18, -10, 0, -9, 8, -2, 0, -8, -15, 12, -8, 2, 10, 4, -7, -3, 9, -1, 3, -13, -6, -9, -13, 11, 4, 4, 4, 1, -19, 13, 4, 0, -10, -13, -1, 11, -9, 5, 4, 8, -6, -13, -1, 13, -9, 2, 12, -21, -9, -7, -13, 1, 2, 4, -6, -22, 4, -10, -9, 0, 3, 15, -1, -15, -22, -4, 19, 4, -14, 7, 1, 1, -9, -15, -7, -6, 8, 10, 0, 9, -3, -13, -13, -4, 0, 0, 11, 8, 20, -4, -11, 0, 6, 4, 8, -3, -16, 10, -5, -6, 7, -3, 17, 12, -5, 4, 12, 2, -2, -10, 3, -6, 2, 4, 0, 7, -2, -12, 5, -15, 12, 12, 3, 5, 4, -10, -1, 10, -3, -9, -9, 6, -13, -7, -7, 6, 6, -1, 4, -4, -2, 7, -6, -5, 18, 0, -10, 6, 4, -7, -16, 12, -6, 13, 9, 16, 3, 4, 9, -5, 4, 4, 7, -17, 17, -3, -5, -5, 2, 8, -6, -8, 18, -4, -4, -10, -13, -5, -1, -8, -10, 3, -3, 9, 9, -21, -2, 5, -3, -11, -4, 3, 4, -6, 8, 0, -7, 7, 22, -6, -12, 7, 11, -9, -22, 7, 3, -9, 11, -24, -7, 7, 13, -1, -4, -1, 12, -6, -20, 8, 6, 10, 1, -3, 17, 2, -7, 14, 24, 6, 12, -7, -1, -2, -9, -16, -8, 2, -11, -5, 1, -3, 7, 14, 16, 4, 16, 6, -1, -4, -2, 22, 16, -10, 7, -6, -7, -12, 3, 8, -2, 23, 11, 4, 6, 18, -1, 14, 10, -2, 5, 11, 1, -3, -5, 5, 15, -21, 7, -4, -13, -6, -4, 2, 6, -5, -11, 11, -5, -8, 20, 4, -4, -12, -2, 4, 21, -6, 5, -1, 7, 15, -18, 1, -7, 0, -10, -23, 8, -8, 9, -1, -6, -8, 7, 17, 11, -8, 14, -3, 3, 0, 8, -10, -10, -5, 3, 2, 16, 0, 13, 5, -18, 10, -10, 14, 10, 7, -6, 14, -22, 2, 2, -1, -11, -2, 11, -1, 3, -7, 12, 2, 4, -9, 9, 22, 2, -6, 7, 4, -12, 7, -14, -4, -12, 8, -4, -18, -4, 14, 16, 12, 9, -9, 5, -3, -7, -16, -2, -7, 7, -11, 11, 14, 5, 1, -4, -5, 10, -8, -1, -8, -6, 19, 1, 5, 2, -6, -3, -7, -9, 21, -14, 3, 9, -5, -15, -14, -1, 6, -8, 2, 11, -12, 1, 6, -18, -12, -8, -3, 1, 1, 3, 4, -9, -5, 14, -7, -7, 1, 3, -4, -20, -2, 2, 16, -3, 1, -8, -3, 24, -15, -6, -16, 7, -15, -12, 7, 2, -2, 8, -15, 1, 19, -10, -5, -1, -14, -9, -5, 5, -4, -6, 3, 2, -21, -3, 16, -24, 8, 0, -6, -14, 13, 13, -9, -10, 18, 4, -3, -10, -3, -13, -6, 22, -9, -7, 8, 5, 7, 10, 0, 0, -2, 6, 7, -6, 4, -19, 12, 18, 5, -20, 13, 5, 3, 4, -17, 1, 12, 2, 1, 8, 18, -10, 20, -14, -20, -13, -6, 6, -14, 1, 18, 9, -18, -2, 5, 23, 13, 6, 3, -11, -20, 6, -10, -13, -9, -15, 13, 6, -6, -1, -8, 3, 10, -4, 11, 7, 6, 2, 0, -7, -5, 14, -6, 9, 5, 11, -3, -3, 14, 15, 12, 7, -9, 11, -17, -3, 5, 9, -15, 5, 0, -11, -10, -7, 9, -4, 9, -2, -4, -2, -5, 2, 16, 15, -7, -5, -16, -6, -16, -7, 1, -5, 14, 8, 3, 8, -2, -5, -13, -7, -7, -3, 23, -4, 12, -20, 3, 18, -2, 7, -9, 1, 21, 6, 5, 15, 2, -2, 5, -8, 12, -16, -6, 4, 24, -18, -7, 6, 14, -2, -19, 9, -1, -2, -3, -7, -12, -24, 22, 17, 4, -12, -19, -13, 5, 20, 11, -2, 6, 15, 11, -8, -2, -18, -6, -14, -14, -1, -5, 0, -4, 10, -10, -1, -17, -13, -24, 6, -5, 7, -16, 5, -4, -11, 4, 3, -11, -13, -15, 13, -8, 0, 1, -3, -6, 3, 12, 8, 19, -5, -8, 5, -17, 8, 6, -23, -10, -12, -6, 4, 21, -13, 8, -17, -12, -10, 18, 6, 2, -3, 15, -11, -14, 3, -11, 4, 3, -13, 2, -11, -16, -1, 2, -11, -6, 4, 9, 3, -5, -3, 13, 10, -16, 14, 9, -12, 1, 12, 10, -9, 0, 9, -2, -7, 10, 9, -6, 18, -12, -12, 3, -18, 15, 10, -4, 14, 0, -6, -1, 4, 2, -13, 19, -6, -5, 3, 9, -7, -5, 8, -1, 19, 2, 2, -12, -3, 4, -4, -7, -1, -9, 11, 13, -11, 4, 2, 11, 4, -1, -6, 22, -5, -13, 2, -6, -8, -7, 4, -17, -3, -1, -3, 13, 1, 7, -9, -8, 0, -15, -7, 1, 17, 11, -13, -6, 6, -6, -17, -21, -8, -14, -3, -3, -4, -5, -8, 7, 13, 18, -16, 4, 18, -7, 1, -8, -7, 5, 0, 16, 0, 15, 2, -3, -10, 5, 15, -2, 19, 1, 11, 9, 11, 9, 9, -8, 5, 11, -16, -2, 11, 15, 17, -10, 10, 11, -13, 8, -1, 24, -13, -6, 5, 4, 0, -16, -13, 8, -3, 5, 15, 1, -8, -15, 11, -11, 8, 8, 14, -21, -16, 3, 9, 15, 14, 3, 13, -6, 7, 7, -1, 1, 3, 11, 8, -17, -3, -9, -8, 2, 7, -1, -4, 13, 12, 17, -5, 11, 5, 1, -4, -4, -15, 2, -5, -22, 2, 2, 24, 0, 1, -18, 9, 14, 12, 3, 0, -9, 8, 6, -14, 9, 18, 0, 15, 1, -7, 4, -18, -2, -2, 13, -3, -3, -6, 7, -2, 12, 10, 2, -6, -15, -2, 1, 6, -1, -5, -3, 16, -7, 10, 13, -1, 0, 0, 10, 5, -4, -6, -12, 2, -13, -7, -4, -2, -16, -11, 3, 0, -15, -18, -3, 12, 6, 9, -12, -7, 19, -22, 3, 10, -9, 10, 14, -2, -3, 9, 5, -11, 2, 24, 0, 20, -6, 8, 19, 2, 7, 8, -9, -10, 6, 3, -13, -3, -13, 7, -8, 0, -19, -9, 2, -11, 3, 8, 7, -12, -20, -8, -5, 17, -5, 7, -2, -7, -11, 3, 10, -12, 9, 5, 9, 11, 8, -17, -14, 10, 1, -11, -17, 2, -8, -12, 4, 4, 14, -1, -16, 16, 5, -15, 23, 19, -2, 3, -5, 4, 2, -17, 6, -7, 16, 22, -4
    };

    if (i_max(width, height) < 800)
    {
      _nbhd_width = 33;
      _kernel_width = 5;  /*the base smooth kernel width for intensity sampling*/
      size_offset = sizeof(offset_33x33) / sizeof(int);
      assert(size_offset == 2048);
      i_copy(offset_33x33, _offset, size_offset);
    }
    else
    {
      _nbhd_width = 49;
      _kernel_width = 7;  /*the base smooth kernel width for intensity sampling*/
      size_offset = sizeof(offset_49x49) / sizeof(int);
      assert(size_offset == 2048);
      i_copy(offset_49x49, _offset, size_offset);
    }

    /*int i = 0, i4 = 0, ix0, iy0, ix1, iy1, dx, dy, rseed = I_DEFAULT_SEED;
    const int nbhd_radius = (_nbhd_width >> 1);
    const double sigma = (double)_nbhd_width / 5;
    const int sigma2 = i_round(sigma*sigma);

    while (i != 512)
    {
    ix0 = i_round(i_rand_gaussian_core_d(rseed, 0, sigma)) + nbhd_radius;
    while (!i_within_1d(ix0, 0, _nbhd_width))
    {
    ix0 = i_round(i_rand_gaussian_core_d(rseed, 0, sigma)) + nbhd_radius;
    }

    iy0 = i_round(i_rand_gaussian_core_d(rseed, 0, sigma)) + nbhd_radius;
    while (!i_within_1d(iy0, 0, _nbhd_width))
    {
    iy0 = i_round(i_rand_gaussian_core_d(rseed, 0, sigma)) + nbhd_radius;
    }

    ix1 = i_round(i_rand_gaussian_core_d(rseed, 0, sigma)) + nbhd_radius;
    while (!i_within_1d(ix1, 0, _nbhd_width))
    {
    ix1 = i_round(i_rand_gaussian_core_d(rseed, 0, sigma)) + nbhd_radius;
    }

    iy1 = i_round(i_rand_gaussian_core_d(rseed, 0, sigma)) + nbhd_radius;
    while (!i_within_1d(iy1, 0, _nbhd_width))
    {
    iy1 = i_round(i_rand_gaussian_core_d(rseed, 0, sigma)) + nbhd_radius;
    }

    dx = (ix1 - ix0);
    dy = (iy1 - iy0);

    if ( (dx*dx + dy*dy) > sigma2 )
    {
    i4 = (i << 2);
    _offset[i4    ] = ix0 - nbhd_radius;
    _offset[i4 + 1] = iy0 - nbhd_radius;
    _offset[i4 + 2] = ix1 - nbhd_radius;
    _offset[i4 + 3] = iy1 - nbhd_radius;
    i++;
    }
    }*/
  }

  InterestPointDescriptorBrief::~InterestPointDescriptorBrief(){}

  void InterestPointDescriptorBrief::describe(const float *const *integral, std::vector<InterestPointBrief128> &ipts, bool upright)
  {
    int i, j;
    int nr_ipts = (int)ipts.size();
    int nr_loops = nr_ipts / 8;
    int nr_remainder = nr_ipts % 8;
    if (upright)
    {
      for (j = 0; j < nr_remainder; ++j)
      {
        describeUpright(integral, ipts.at(j));
      }
      for (i = 0, j = nr_remainder; i < nr_loops; ++i)
      {
        describeUpright(integral, ipts.at(j++));//1
        describeUpright(integral, ipts.at(j++));//2
        describeUpright(integral, ipts.at(j++));//3
        describeUpright(integral, ipts.at(j++));//4
        describeUpright(integral, ipts.at(j++));//5
        describeUpright(integral, ipts.at(j++));//6
        describeUpright(integral, ipts.at(j++));//7
        describeUpright(integral, ipts.at(j++));//8
      }
    }
    else
    {
      /*empty implementation for now*/
    }
  }

  void InterestPointDescriptorBrief::describe(const float *const *integral, std::vector<InterestPointBrief256> &ipts, bool upright)
  {
    int i, j;
    int nr_ipts = (int)ipts.size();
    int nr_loops = nr_ipts / 8;
    int nr_remainder = nr_ipts % 8;
    if (upright)
    {
      for (j = 0; j < nr_remainder; ++j)
      {
        describeUpright(integral, ipts.at(j));
      }
      for (i = 0, j = nr_remainder; i < nr_loops; ++i)
      {
        describeUpright(integral, ipts.at(j++));//1
        describeUpright(integral, ipts.at(j++));//2
        describeUpright(integral, ipts.at(j++));//3
        describeUpright(integral, ipts.at(j++));//4
        describeUpright(integral, ipts.at(j++));//5
        describeUpright(integral, ipts.at(j++));//6
        describeUpright(integral, ipts.at(j++));//7
        describeUpright(integral, ipts.at(j++));//8
      }
    }
    else
    {
      /*empty implementation for now*/
    }
  }

  void InterestPointDescriptorBrief::describe(const float *const *integral, std::vector<InterestPointBrief512> &ipts, bool upright)
  {
    int i, j;
    int nr_ipts = (int)ipts.size();
    int nr_loops = nr_ipts / 8;
    int nr_remainder = nr_ipts % 8;
    if (upright)
    {
      for (j = 0; j < nr_remainder; ++j)
      {
        describeUpright(integral, ipts.at(j));
      }
      for (i = 0, j = nr_remainder; i < nr_loops; ++i)
      {
        describeUpright(integral, ipts.at(j++));//1
        describeUpright(integral, ipts.at(j++));//2
        describeUpright(integral, ipts.at(j++));//3
        describeUpright(integral, ipts.at(j++));//4
        describeUpright(integral, ipts.at(j++));//5
        describeUpright(integral, ipts.at(j++));//6
        describeUpright(integral, ipts.at(j++));//7
        describeUpright(integral, ipts.at(j++));//8
      }
    }
    else
    {
      /*empty implementation for now*/
    }
  }

  inline void InterestPointDescriptorBrief::describeUpright(const float *const *integral, InterestPointBrief128 &ipt)
  {
    static const int nr_comp = 128;
    const int base_rad = (_kernel_width >> 1);
    float sf, v0, v1;
    int i, i4, j = 0, pos = 0, dx, dy, x0, y0, x1, y1, rec_rad, rec_width, area;
    unsigned int code = 0;

    sf = i_div(ipt.scale, _base_scale);
    //rec_rad = i_round(base_rad * sf);
    rec_rad = i_round(base_rad * i_sqrt(sf));
    rec_width = (rec_rad << 1) + 1;

    dx = i_round(ipt.x) - rec_rad;
    dy = i_round(ipt.y) - rec_rad;

    for (i = 0; i < nr_comp; ++i)
    {
      i4 = (i << 2);
      /*get point a's coord*/
      x0 = i_round(_offset[i4] * sf) + dx;
      y0 = i_round(_offset[i4 + 1] * sf) + dy;

      /*get point b's coord*/
      x1 = i_round(_offset[i4 + 2] * sf) + dx;
      y1 = i_round(_offset[i4 + 3] * sf) + dy;

      /*sample point a's value within a rectangular area*/
      v0 = i_integral_rect(integral, x0, y0, rec_width, rec_width, _width, _height, area);
      v0 /= area;
      /*sample point b's value within a rectangular area*/
      v1 = i_integral_rect(integral, x1, y1, rec_width, rec_width, _width, _height, area);
      v1 /= area;

      /*compare a < b?*/
      if (v0 < v1)
      {
        code = (code << 1) | 1;
      }
      else
      {
        code = (code << 1);
      }
      if (32 == (++j))
      {
        ipt.descriptor[pos++] = code;
        code = j = 0;
      }
    }
  }

  inline void InterestPointDescriptorBrief::describeUpright(const float *const *integral, InterestPointBrief256 &ipt)
  {
    static const int nr_comp = 256;
    const int base_rad = (_kernel_width >> 1);
    float sf, v0, v1;
    int i, i4, j = 0, pos = 0, dx, dy, x0, y0, x1, y1, rec_rad, rec_width, area;
    unsigned int code = 0;

    sf = i_div(ipt.scale, _base_scale);
    //rec_rad = i_round(base_rad * sf);
    rec_rad = i_round(base_rad * i_sqrt(sf));
    rec_width = (rec_rad << 1) + 1; /*width = 2*r + 1*/

    dx = i_round(ipt.x) - rec_rad;
    dy = i_round(ipt.y) - rec_rad;

    for (i = 0; i < nr_comp; ++i)
    {
      i4 = (i << 2);
      /*get point a's coord*/
      x0 = i_round(_offset[i4] * sf) + dx;
      y0 = i_round(_offset[i4 + 1] * sf) + dy;

      /*get point b's coord*/
      x1 = i_round(_offset[i4 + 2] * sf) + dx;
      y1 = i_round(_offset[i4 + 3] * sf) + dy;

      /*sample point a's value within a rectangular area*/
      v0 = i_integral_rect(integral, x0, y0, rec_width, rec_width, _width, _height, area);
      v0 /= area; //normalize
      /*sample point b's value within a rectangular area*/
      v1 = i_integral_rect(integral, x1, y1, rec_width, rec_width, _width, _height, area);
      v1 /= area; //normalize

#if 1
      /*compare a < b?*/
      if (v0 < v1)
      {
        code = (code << 1) | 1;
      }
      else
      {
        code = (code << 1);
      }
      if (32 == (++j))
      {
        ipt.descriptor[pos++] = code;
        code = j = 0;
      }
#endif

#if 0
      float Thre = 5.f / 255;
      /*compare a < b?*/
      if (v0  < v1 - Thre)
      {
        /*10*/
        code = (code << 2) | 2;
      }
      else if (v0  > v1 + Thre)
      {
        /*01*/
        code = (code << 2) | 1;
      }
      else
      {
        /*00*/
        code = (code << 2);
      }

      if (16 == (++j))
      {
        ipt.descriptor[pos++] = code;
        code = j = 0;
      }
#endif
    }
  }

  inline void InterestPointDescriptorBrief::describeUpright(const float *const *integral, InterestPointBrief512 &ipt)
  {
    static const int nr_comp = 512;
    const int base_rad = (_kernel_width >> 1);
    float sf, v0, v1;
    int i, i4, j = 0, pos = 0, dx, dy, x0, y0, x1, y1, rec_rad, rec_width, area;
    unsigned int code = 0;

    sf = i_div(ipt.scale, _base_scale);
    //rec_rad = i_round(base_rad * sf);
    rec_rad = i_round(base_rad * i_sqrt(sf));
    rec_width = (rec_rad << 1) + 1;

    dx = i_round(ipt.x) - rec_rad;
    dy = i_round(ipt.y) - rec_rad;

    for (i = 0; i < nr_comp; ++i)
    {
      i4 = (i << 2);
      /*get point a's coord*/
      x0 = i_round(_offset[i4] * sf) + dx;
      y0 = i_round(_offset[i4 + 1] * sf) + dy;

      /*get point b's coord*/
      x1 = i_round(_offset[i4 + 2] * sf) + dx;
      y1 = i_round(_offset[i4 + 3] * sf) + dy;

      /*sample point a's value within a rectangular area*/
      v0 = i_integral_rect(integral, x0, y0, rec_width, rec_width, _width, _height, area);
      v0 /= area; //normalize
      /*sample point b's value within a rectangular area*/
      v1 = i_integral_rect(integral, x1, y1, rec_width, rec_width, _width, _height, area);
      v1 /= area; //normalize
      /*compare a < b?*/
      if (v0 < v1)
      {
        code = (code << 1) | 1;
      }
      else
      {
        code = (code << 1);
      }

      if (32 == (++j))
      {
        ipt.descriptor[pos++] = code;
        code = j = 0;
      }
    }
  }

}/*namespace idl*/